home *** CD-ROM | disk | FTP | other *** search
- ; CL-Print.asm;
- CR Equ 13
- LF Equ 10
- BELL Equ 7
- TAB Equ 9
- SWITCH Equ '/'
-
- CODE SEGMENT ;*************************
- ASSUME CS:CODE,DS:CODE ;* *
- Org 100H ;* REMEMBER TO EXE2BIN *
- ;* *
- Start: Jmp Beginning ;*************************
-
-
- ; Data Area
- ; ---------
-
- Copyright$ DB CR,LF,'CL-Print Ver 2.40 - '
- DB 'Copyright 1991,1992 Gary Meeker',CR,LF,'"'
- Comment$ DB 62 DUP (' '), CR, LF, 1AH
- Quote2$ DB '"=>$'
- File_Start DW ? ;Points to Asciiz Filename
- Commands DB 'BQN*Z'
- BiosDos DB 0FFH ;0=Bios, -1=DOS Time/Date
- Quiet DB 0FFH ;0=Quiet, -1=Copyright Display
- NoAppend DB 0FFH ;0=No Append, -1=Append
- Close_It DB 0FFH ;0=write 62 *'s
- ASCIIZ$ DB ' ' ;0=ASCIIZ, Space
- Usage_Msg DB BELL,CR,LF
- DB 'Usage: CL-PRINT filespec "logstring"',CR,LF,LF
- DB ' String must be in quotes or decimal ASCII - '
- DB 'Seperate multiple codes by commas.',CR,LF,LF
- ; DB ' e.g. CL-PRINT C:\PCB\CALLER /S,"Scheduled Event Ended /A"',CR,LF,LF
- DB TAB,'/A = " at MM-DD-YY HH:MM:SS"',CR,LF
- DB TAB,'/D = "MM-DD-YY"',CR,LF
- DB TAB,'/L = "MM-DD-YY (HH:MM)"',CR,LF
- DB TAB,'/S = 6 spaces',CR,LF
- DB TAB,'/T = "HH:MM"',CR,LF
- DB TAB,'/* = row of *',CR,LF
- DB TAB,'/Q = No console output',CR,LF
- DB TAB,'/N = Create NEW file'
- DB TAB,'/B = use BIOS Date/Time Services '
- CrLf$ DB CR,LF,'$'
- NoUser$ DB BELL,CR,LF,'No User Online!',CR,LF,'$'
-
- PCBDrive DB 'PCBDRIVE='
- LenPCBDrive EQU $ - PCBDrive
-
- PCBDir DB 'PCBDIR='
- LenPCBDir EQU $ - PCBDir
-
- PCBoardSys$ DB 'PCBOARD.SYS',0
- PCBoardDat$ DB 'PCBOARD.DAT',0
-
- Not_Found2 DB ' - File not found! ',CR,LF,'$'
- Not_Found3 DB ' - Path not found! ',CR,LF,'$'
- No_Handle DB ' - No handles left!',CR,LF,'$'
- No_Access DB ' - Access Denied!',CR,LF,'$'
- Unknown DB ' - Unknown Error!',CR,LF,'$'
- ReadError$ DB ' - Error reading file!',CR,LF,'$'
-
- ; Code Area
- ; ---------
-
- ;-------------------------------------------------------;
- ; First we will parse the filename and the string. ;
- ;-------------------------------------------------------;
-
- Beginning: Mov DX,OFFSET Usage_Msg ;Point to syntax message.
- Cld ;Move in forward direction.
- Mov AX,DS ;Point ES to DS
- Mov ES,AX
- Mov SI,80H ;Point to parameters.
- Mov DI,81H ;Point DI for SCASB
- Mov AL,'@' ;See if any @ Variables exist
- Xor CH,CH ;Get Command Line
- Mov CL,[SI] ; Length in CX
- Jcxz ErrorExit ;Nevermind if no parameters
- Repne Scasb ;Do we have any @ variables
- Jne No_Read ;Nope, None found
- Call ReadFile ;Yep, Read PCBoard files into
- Jc ErrorExit ; buffers, oops Error occured
- No_Read: Mov DI,OFFSET Comment$ ;Point to comment string storage.
- Xor CX,CX ;Set string counter to zero.
- Call Space ;Parse leading spaces.
- Mov File_Start,SI ;We now point to filename.
-
- File_Byte: Cmp BYTE PTR [SI],CR ;Is it a carriage return?
- Jz ErrorExit ;If yes, exit with syntax error.
- Cmp BYTE PTR [SI],' ' ;Is it a space?
- Jz Asciiz ;If yes, end of filename
- Inc SI ; else, point to next byte
- Jmp File_Byte ; and check it.
-
- OpenError: Call File_Error ;Show what type of Error
- ErrorExit: Call Display
- Mov AX,4C01H
- Int 21H ; and terminate.
-
- Asciiz: Mov BYTE PTR [SI],0 ;Make filename into ASCIIZ.
-
- Call Space ;Parse the spaces.
- String_Byte: Call String ;Get string.
- Cmp BYTE PTR [SI],CR ;Are we now pointing to CR?
- Jz Open_File ;If yes, we are done here
- Inc SI ; else point to next byte
- Cmp CX,62 ;Maximum Length?
- Jl String_Byte ; No, get rest of string.
-
- ;------------------------------------------;
- ; OK, Open file and seek to the end of it. ;
- ;------------------------------------------;
-
- Open_File: Push CX ;Save length
- Mov DX,File_Start ;Point to ASCIIZ filename
- Cmp NoAppend, 0 ;Is it NoAppend mode?
- Je Create_File ;Yes, Just create it!
- Mov AX,3D41H ; Open file for writing.
- Int 21H
- Jnc Open2 ;OK if no error
- Cmp AX,2 ;Was it NOT FOUND?
- Jne OpenError ; No, Report the error
- Create_File: Mov AH,3CH ; Yes, Create File
- Xor CX,CX ; Normal Attribute
- Int 21H
- Jc OpenError ;Report the error
-
- Open2: Mov BX,AX ;File Handle to BX
- Mov AX,4202H ;No, Move File Pointer
- Xor CX,CX ; Zero offset
- Xor DX,DX ; from end of file (CX:DX = 0)
- Int 21H
- Pop CX
-
- ;------------------------------------------------;
- ; We are ready to write the comment to the file. ;
- ;------------------------------------------------;
-
- Write: Jcxz Skip_Write
- Mov DX,OFFSET Comment$ ;Point to COMMENT$
- Jmp SHORT Write_Close ;Write the comment
- Make_Close: Call Do_Close ;Fill the Buffer
- Write_Close: Mov CX,64 ;64 Bytes to write
- Mov AH,40H ; and write comment.
- Int 21H
- Skip_Write: Cmp Close_It,0FFH ;Do we need a row of *,s
- Jne Make_Close ;yes
- Mov AH,3EH ;No,close file.
- Int 21H
- Cmp Quiet,0FFh ;Quiet Mode
- Jne QExit ;Yes, So Exit
- Mov Comment$+62,'$' ;No, prepare the Comment
- Mov DX,OFFSET Copyright$ ;Point to Copyright message
- Call Display
- Mov DX,OFFSET Quote2$ ;Print trailing Quote & Arrow
- Call Display
- Mov SI,File_Start ;Point to File Name
- Call DisplayText
-
- ;------------------------------------------;
- ; The exit is placed in the middle of code ;
- ; so it can be reached by short jumps. ;
- ;------------------------------------------;
-
- Exit2: Mov DX,OFFSET CrLf$
- Exit: Call Display
- QExit: Mov AX,4C00H
- Int 21H ; and terminate.
-
- File_Error: Mov DX,OFFSET Not_Found2
- Cmp AX,2
- Je Error_Ret
- Mov DX,OFFSET Not_Found3
- Cmp AX,3
- Je Error_Ret
- Mov DX,OFFSET No_Handle
- Cmp AX,4
- Je Error_Ret
- Mov DX,OFFSET No_Access
- Cmp AX,5
- Je Error_Ret
- Mov DX,OFFSET Unknown
- Error_Ret: Ret
-
- ;---------------------------------------;
- ; This subroutine will use DOS function ;
- ; to print string terminated by '$' ;
- ;---------------------------------------;
-
- Display: Mov AH,9 ;Display message
- Int 21H ;
- Ret ;
-
-
- ;---------------------------------------------;
- ; This subroutine will get the quoted string ;
- ; or convert the decimal ASCII to hexadecimal ;
- ; and store in the appropriate storage area. ;
- ;---------------------------------------------;
-
- String: Mov AH,[SI] ;Get a character
- Cmp AH,'"' ;Is it double quotes?
- Jz Got_Quote ;Yes -
- Cmp AH,"'" ;No - Is it single quotes?
- Jnz Number ;If no, must be number
- Got_Quote: Inc SI ; else, point to first string
- Next_String: Lodsb ; byte and retrieve.
- Cmp AL,CR ;Is it carriage return?
- Jz Exit ;If yes, syntax error; exit.
- Cmp AL,SWITCH ;Is it a Switch character
- Jz Is_Switch ;Yes
- Cmp AL,'@' ;No, Is it a Var Subst Char?
- Jnz Not_switch ;No,
- Is_Switch: Call Substitute ;Yes, Substitute
- Jnc Next_2 ; If Not carry then continue
- Ret ; else done
- Not_Switch: Cmp AL,AH ;Is it a matching quotes?
- Jnz Store ;If no, store the byte
- Call Delimiter ; else, see if delimiter
- Jnc Store ; and store the quote if part
- Ret ; of string else, we are done.
-
- Store: Stosb ;Store the byte
- Inc CX ; increment byte count
- Next_2: Cmp CX,62 ;Maximum length?
- Jl Next_String ; no, get next string byte
- Ret ; yes, then return
-
- ;-------------------------------;
- ; This routine converts Decimal ;
- ; Ascii number to charcater and ;
- ; places it in Comment$ ;
- ;-------------------------------;
-
- Number: Xor BL,BL ;Zero into hex counter.
- Cmp AH,Switch ;Was it a Switch character?
- Jz Is_Switch2 ;Yes
- Cmp AH,'@' ;No, Is it a Var Subst char?
- Jnz Get_Number ;No, must be a number
- Is_Switch2: Inc SI ;Yes, Skip the Switch Char
- Mov AL,AH ;Copy Switch to AL
- Jmp SHORT Substitute ;Do the substitute
- Get_Number: Call Delimiter ;Is it a delimiter?
- Jnc Load_Number ;If no, get next decimal number
- Mov AL,BL ; get hex byte
- Stosb ; and store
- Inc CX ; increment byte count
- Ret ; yes, then return
- Jump2Exit: Jmp Exit
-
- Load_Number: Lodsb ;Get the decimal number
- Cmp AL,'0' ;Is it between 0 and 9?
- Jb Jump2Exit ;If no, syntax error
- Cmp AL,'9'
- Ja Jump2Exit
- Sub AL,30H ; else, convert to hex
- Mov BH,AL ; and save
- Mov AL,10 ; multiply by ten
- Mul BL ; to shift place left
- Mov BL,AL
- Add BL,BH ; add new number
- Jmp Get_Number ; and get next decimal number.
-
- ;------------------------------------------------;
- ; This subroutine converts '/' variables to ;
- ; their values and stuffs Comment$ ;
- ;------------------------------------------------;
-
- Substitute: Push AX ;Save Quote
- Mov AH,AL ;Save the switch
- Lodsb ;Get the next Character
- Cmp AL,'a' ;Lower Case?
- Jb S1 ;No,
- Cmp AL,'z' ;Maybe, let's see
- Ja S1 ;No,
- Sub AL,20h ;Yes, convert to Upper Case
- S1: Cmp AH,Switch ;Is it a switch or Var Subst?
- Je Do_Switch ;It was a Switch?
- Jmp VarSub ;No, It was a Var Subst?
- Do_Switch: Mov BX,5 ;5 commands to check
- Next_Cmp: Cmp AL,Commands-1[BX] ;Is this the one?
- Je Set_Mode ;Yes
- Dec BX ;No, Decrement BX
- Jnz Next_Cmp ;Loop until Done
- ;---------------------------------------------------------------------------
- ; Cmp AL,'Q' ;Is it QUIET Switch?
- ; code Je Set_Quiet ;Yes (Carry is Cleared)
- ; replaced Cmp AL,'N' ;Is it NoAppend mode?
- ; by 5 Je Set_NoAppend ;Yes, (Carry is Cleared)
- ; lines Cmp AL,'B' ;Is it BIOS services mode?
- ; above Je Set_TimeDate ;Yes, (Carry is Cleared)
- ; Cmp AL,'*' ;No, Is it CLOSED Var?
- ; Je Set_Closed ;Yes (Carry is Cleared)
- ; Cmp AL,'Z' ;Is it a ASCIIZ var?
- ; Je Set_ASCIIZ ;Yes, Carry is Cleared
- ;---------------------------------------------------------------------------
- Cmp AL,CR ;Is it CR?
- Je Jump2Exit ;If yes, syntax error; exit.
- Mov BX,DI ;Save COMMENT$ Pointer
- Mov DI,OFFSET DatBuffer ;Point to Buffer
- Cmp AL,'T' ;Is it TIME var?
- Je Stuff_Time ;Yes, and Carry is Clear
- Cmp AL,'D' ;Is it DATE Var?
- Je Stuff_Date ;No,
- Cmp AL,'A' ;Maybe, let's see
- Jnz S2 ;No,
- Mov AX,'a ' ;Yes, Set ' at ' in Buffer
- Stosw ;
- Mov AX,' t' ;
- Stosw ;
- Call Do_Date ;add Date to Buffer
- Mov AL,' ' ;add ' '
- Stosb ;
- Stc ;We want seconds too
- Stuff_Time: Call DO_Time ;add Time to Buffer
- Jmp SHORT Stuff_It
- S2: Cmp AL,'L' ;Is it LOGON Var?
- Jne S3 ;No,
- Call Do_Date ;Yes, Set Date in Buffer
- Mov AX,'( ' ; add ' ('
- Stosw ;
- Clc ;We don't want seconds
- Call Do_Time ;add Time to Buffer
- Mov AL,')' ; add ')'
- Stosb ;
- Jmp SHORT Stuff_It
- S3: Cmp AL,'S' ;Is it SPACES var?
- Jne S4 ;No,
- Mov AX,' ' ;Yes, Set six spaces in Buffer
- Stosw ;
- Stosw ;
- Stosw ;
- Jmp SHORT Stuff_It
- S4: Mov DI,BX ;restore Comment$ pointer
- Stosb ;just store it
- Inc CX ;count it
- Clc ;
- Pop AX ;Restore Quote
- Ret
- Set_Mode: Mov BiosDOS-1[BX],BH ;Handles all 5 Set variables, BH=0
- Pop AX ;Restore Quote
- Ret ;Done - Carry Clear
-
- ;---------------------------------------------------------------------------
- ;Set_ASCIIZ: Mov BYTE PTR ASCIIZ$,0 ;Set 0 in ASCIIZ$
- ; Pop AX ;Restore Quote
- ; Ret ;Done - Carry Clear
- ;Set_Quiet: Mov BYTE PTR Quiet,0 ;Show Quiet mode
- ; Pop AX ;Restore Quote
- ; Ret ;Done - Carry Clear
- ;Set_NoAppend: Mov BYTE PTR NoAppend,0 ;Show NoAppend mode
- ; Pop AX ;Restore Quote
- ; Ret ;Done - Carry Clear
- ;Set_TimeDate: Mov BYTE PTR BiosDos,0 ;Show BIOS Services used
- ; Pop AX ;Restore Quote
- ; Ret ;Done - Carry Clear
- ;Set_Closed: Mov BYTE PTR Close_It,0 ;Show Closed mode
- ; Pop AX ;Restore Quote
- ; Ret ;Done - Carry Clear
- ;---------------------------------------------------------------------------
-
-
- Stuff_Date: Call Do_Date ;Yes, Set Date in Buffer
- Stuff_It: Xor AL,AL ;Zero marks end of data
- Stosb ;
- Mov DI,BX ;resore Comment$ pointer
- Mov BX,SI ;Save Command Line pointer
- Mov SI,OFFSET DatBuffer ;Point to Buffer
- Stuff_More: Lodsb ;Get character from Buffer
- Or AL,AL ;End of data
- Jz Done_Stuff ;Yes,
- Stosb ;Copy to Comment$
- Inc CX ;Count it
- Cmp CX,62 ;Maximum Length?
- Jl Stuff_More ;No - Continue
- Stc ;Yes - Indicate that
- Done_Stuff: Mov SI,BX ;Restore Command Line pointer
- Pop AX ;Restore Quote
- Ret ;All done
-
- ;------------------------------------------;
- ; This subroutine Reads Date and stuffs ;
- ; buffer with information (uses part of ;
- ; Do_Time routine) ;
- ;------------------------------------------;
-
- Do_Date: Push BX ;Save BX
- Push CX ;Save Length
- Push DX ;Save Message Pointer
- Test BiosDOS,0 ;Get flag
- Jne DosDate ;We use DOS
- Mov AH,04H ;Get date service
- Int 1AH ;Call BIOS - return codes as follows:
- ;CH = Century (19-20) CL = Year (00-99)
- ;DH = Month (1-12) DL = Day (00-31)
- Jmp SHORT Do_Date1
- DosDate: Mov AH,2AH ;Get System Date
- Int 21H ;DOS Call
- Sub CX,1900 ;Remove Century
- Do_Date1: Mov AL,DH ;Month
- Call ASCII ;Convert byte to ASCII digits
- Mov AL,'-' ;
- Stosb ;
- Mov AL,DL ;Day
- Call ASCII ;Convert byte to ASCII digits
- Mov AL,'-' ;
- Stosb ;
- Mov AL,CL ;Year
- Jmp SHORT Skip_Seconds
-
- ;------------------------------------------;
- ; This subroutine Reads Time and stuffs ;
- ; buffer with information ;
- ;------------------------------------------;
-
- Do_Time: Push BX ;Save BX
- Push CX ;Save Length
- Push DX ;Save Message Pointer
- PushF ;Save Flags
- Test BiosDOS,0 ;Get flag
- Jne DosTime ;We use DOS
- Mov AH,02H ;Get time service
- Int 1AH ;Call BIOS - return codes as follows:
- ;CH = Hours (0-23) CL = Minutes (0-59)
- ;DH = Seconds (0-59)
- Jmp SHORT Do_Time1
- DosTime: Mov AH,2CH ;Get System Time
- Int 21H ;DOS Call
- Do_Time1: Mov AL,CH ;Hours
- Call ASCII ;Convert byte to ASCII digits
- Mov AL,':' ;
- Stosb ;
- Mov AL,CL ;Minutes
- PopF ;Restore Flags
- Jnc Skip_Seconds ;Skip the Seconds if No Carry
- Call ASCII ;Convert byte to ASCII digits
- Mov AL,':' ;
- Stosb ;
- Mov AL,DH ;Seconds
- Skip_Seconds: Pop DX ;Restore Message Pointer
- Pop CX ;Restore Length
- Pop BX ;Restore BX
- ASCII: Test BiosDos,0 ;Do we use DOS or BIOS
- Jne DosASCII ;We use DOS
- Mov AH,AL ;Need to get BCD Digits
- Shr AL,1 ; MSD in AL
- Shr AL,1 ; lower
- Shr AL,1 ; 4
- Shr AL,1 ; Bits
- And AH,0FH ;And LSD in AH cleanly
- PutAscii: Or AX,3030H ;Convert to ASCII
- Stosw ;Stuff Digits into Buffer (in reverse)
- Ret ;SI Points to String Data
- DosASCII: Mov BL,10 ;Divide by 10
- Xor AH,AH ;Change AL to AX
- Div BL ;Do the Division
- Jmp PutAscii ;and write the digits
-
- ;--------------------------------------------;
- ; This subroutine will translate @ variables ;
- ; to data read from PCBOARD.SYS & USERS file ;
- ;--------------------------------------------;
-
- VarSub: Push DI ;Save Comment$ pointer
- Mov BX,OFFSET SUB_TABLE ;Point to Variable List
- Mov DI,OFFSET DatBuffer ;Point to Buffer
- NextVar: Mov AH,[BX] ;Get a letter from table
- Or AH,AH ;End of table?
- Jz NoSub ;Yes, no match then
- Cmp AH,AL ;No, Is this our Letter?
- Jz GotIt ; Yes,
- Add BX,4 ; No, Bump the pointer
- Jmp NextVar ; Next Variable
- GotIt: Mov AX,[BX][1] ;Get Offset value from table
- Mov CL,[BX][3] ;Get Length value from table
- Xor CH,CH ;Convert to word
- Mov BX,SI ;Save Command line pointer
- Mov SI,OFFSET SysBuffer ;Point to PCBOARD.SYS Buffer
- Add SI,AX ;Add Offset
- VarCopy: Lodsb ;Get Character
- Or AL,AL ;Is it a Zero
- Jnz CopyIt ;No,
- Or AL,ASCIIZ$ ;Yes, Is ASCIIZ$ = 0
- Jz CopyDone ; Yes, Done
- CopyIt: Stosb ; No, Copy it
- Loop VarCopy ;Loop till Done
- ; Rep Movsb ;Copy Variable to Buffer
- CopyDone: Mov SI,BX ;Restore Command line pointer
- Pop BX ;Restore Comment$ Pointer to BX
- Jmp Stuff_It ; Now stuff the data in Comment$
- NoSub: Pop BX ;Restore Comment$ Pointer to BX
- Jmp S4 ;Just store the character
-
- ;--------------------------------;
- ; This subroutine will parse ;
- ; leading and delimiting spaces. ;
- ;--------------------------------;
-
- Space: Inc SI ;Point to next byte
- Cmp BYTE PTR [SI],' ' ;Is it space?
- Jz Space ;If no, get next byte
- Ret ; else, return.
-
- ;----------------------------;
- ; This subroutine will check ;
- ; for delimiter characters. ;
- ;----------------------------;
-
- Delimiter: Push AX
- Mov AL,[SI]
- Clc ;Assume not delimiter.
- Cmp AL,' ' ;Is it space
- Jz Set_Carry
- Cmp AL,CR ; or carriage return
- Jz Set_Carry
- Cmp AL,',' ; or comma?
- Jz Set_Carry
- Cmp AL,';' ; or semi-colon?
- Jz Set_Carry
- Cmp AL,Switch ; or Switch?
- Jnz Return ;If no, return else, indicate
- Set_Carry: Stc ; by setting carry flag
- Return: Pop AX
- Ret ; and return.
-
- ;----------------------------;
- ; This subroutine will fill ;
- ; the buffer with *'s. ;
- ;----------------------------;
-
- Do_Close: Mov DI,Offset DatBuffer ;Point to Buffer for this
- Mov DX,DI ;DX also for Write
- Mov AL,'*' ;Make a line of *'s
- Mov CX,62 ;Need 62 of them
- Rep Stosb ;
- Mov AL,CR ;Add a Carriage Return
- Mov AH,LF ; and Line Feed
- Stosw
- Mov Close_It,0FFh ;Turn Off flag or we will be here
- Ret ; forever - and Return
-
- ;---------------------------------------;
- ; This subroutine will use DOS function ;
- ; to print string terminated by Zero. ;
- ;---------------------------------------;
-
- DisplayText: Lodsb ;get a character
- Or AL,AL ;End of name
- Jz DisplayDone ;Yes, Done
- Mov DL,AL ;No,Print it
- Mov AH,2 ;Character Output
- Int 21H
- Jmp DisplayText ;Loop until done
- DisplayDone: Ret
-
- ;---------------------------------------;
- ; This subroutine will read PCBOARD.SYS ;
- ; file into a buffer area. ;
- ;---------------------------------------;
-
- ReadFile: Push DI ;
- Push SI ;
- Push DX ;Save message pointer
- Xor CX,CX ;Zero Counter for test purposes
- NextFlush: Mov BX,CX ;Let's dup the Stdin handle
- Mov AH,45h ;service to duplicate a file handle
- Int 21h ;call DOS to do it
- Jcxz StartFlush ;First Time thru
- Jmp SHORT CloseIt
- StartFlush: Mov CX,AX ;copy to CX for counter
- CloseIt: Mov BX,AX ;put the new handle into BX
- ; Mov DX,AX ;Copy Handle number
- ; Add DX,3030h ;Make it Ascii
- ; Mov AH,2 ;Display Character
- ; Int 21h ;Let's display the number for testing
- Mov AH,3Eh ;and close the "alias" file
- Int 21h ;call DOS to do it
- Dec CX ;Next Handle
- Cmp CX,4 ;Did we inherit any files?
- Ja NextFlush ;Yes, lets Flush them
- ;No, or we went thru them all!
- DoneFlushing: Mov DI,OFFSET SysBuffer ;Point to PCBoard.Sys Buffer area
- Push DI
- Mov CX,1024 ;Let's fill the whole buffer area
- Mov AL,'.' ; with '.' characters
- Rep Stosb ; and do it
- Mov DX,OFFSET PCBoardSys$ ;Point to Asciiz filename
- Call CheckFile ;See if it's present
- Pop DI
- Mov CX,128 ;128 bytes is all we need
- Xor AX,AX ;No Record Seek
- Call ReadBuffer ;
- Jc ReadErr_Hop ;
- Mov AL,SysBuffer + 84 ;Get the first character (UserName)
- Cmp AL, ' ' ;Is it a space?
- Je NoUser ;Yes
- Mov DX,OFFSET PCBoardDat$ ;Point to Asciiz filename
- Call CheckFile ;See if it's present
- Mov DI,OFFSET DatBuffer ;Point to PCBoard.Dat Buffer area
- Mov CX,8000 ;8000 bytes is more than enough
- Xor AX,AX ;No Record Seek
- Call ReadBuffer
- ReadErr_Hop: Jc ReadError
- Mov DI,OFFSET DatBuffer ;Point to PCBoard.Dat Buffer area
- Mov CX,8000
- Mov BX,28 ;Scan past 28 Lines
- Mov AL,LF
- NextLine: Repne Scasb
- Dec BX
- Jnz NextLine
- Mov DX,DI ;DX points to filename
- Repne Scasb ;Find End of line
- Dec DI ;back up
- Dec DI ;back up
- Mov Byte Ptr [DI],0 ;Make ASCIIZ
- ; Push DX
- ; Mov SI,DX
- ; Call DisplayText ;Lets see that name
- ; Pop DX
- Mov DI,OFFSET UserBuffer ;Point to User File Buffer
- Mov CX,400 ;400 Bytes in User Record
- Mov AX,Word Ptr SYSBuffer+23 ;Get User Record Number
- Or AX,AX ;Test the Record Number
- Jz NoUser ;None present, error
- Push AX ;Save the record Number
- Call ReadBuffer
- Pop CX
- Jc ReadError
- Mov AH,3EH ;Close file
- Int 21H
- Mov DI,OFFSET UserBuffer+229 ;Point to LastMsgConf
- Mov SI,OFFSET UserBuffer+87 ;Point SI to Last Date On
- Mov AX,CX ;Get Record Number
- Call TransferInt2 ;Copy Integer
- Call TransferDate ;Copy Date (DI=DI+8, SI=SI+6)
- Add SI,8 ;Point to Last Scan Date
- Call TransferDate ;Copy Date (DI=DI+8, SI=SI+6)
- Call TransferChr ;Copy Chr$(Seclevel)
- Call TransferInt ;Copy Integer (TimesOn)
- Add SI,73 ;Point to Minutes On
- Call TransferInt ;Copy Integer (Minutes On)
- Call TransferDate ;Copy Date (DI=DI+8, SI=SI+6)
- Call TransferChr ;Copy Chr$(ExpSecLevel)
- Mov AX,Word Ptr SYSBuffer+109 ;Get Time Remaining
- Call TransferInt2 ;Copy Integer
- Mov SI,OFFSET UserBuffer ;Point SI to UserName
- Call TransferFile ;Make it a FileName
- Pop DX ;Restore message pointer
- Clc ;Indicate No Error
- Jmp SHORT ReadError2 ;
- NoUser: Mov DX, OFFSET NoUser$ ;No user Online!
- Stc
- ReadError: Pop AX ;Forget message pointer
- ReadError2: Pop SI
- Pop DI
- Ret
-
- ;---------------------------------------;
- ; Transfer UserName to FileName ;
- ;---------------------------------------;
-
- TransferFile: Mov BL,'.' ; We need a '.', then a 0h
- Mov BH,' ' ; First we need to find space
- Mov AH,254 ; Flag shows we are in FileName, then Ext.
- Mov CX,8 ; Eight Characters Max
- Mov DX,25 ; UserName is 25 characters long
- Next_Char: Lodsb ; Read a Char
- Dec DX ; Count it
- Call CheckChar ; Check for bad characters
- Cmp AL,BH ; Is it a Space?
- Jne Not_Space ; No, continue then
- Inc AH ; Yes, Show we found a Space
- Do_Dot: Mov AL,BL ; Yes, Time for the '.' or 0h
- Not_Space: Stosb ; Store the character
- Cmp AL,BL ; Was it a '.'?
- Je Extension ; Yes
- Loop Next_Char ; No, then loop till all 8
- Jmp Do_Dot ; And now we need a Dot
- Extension: Or BL,BL ; Are we Done (BL = 0)?
- Jz FileDone ; Yes, Bye-bye
- Xor BL,BL ; Zero to BL
- Inc AH ; No, Did we find a Space already?
- Jz Skip_Scan ; Yes, then No need for scan!
- Mov CX,DX ; No, Get Characters remaining in UserName
- Xchg SI,DI ; Scasb needs ES:DI (but we want to scan SI)
- Mov AL,BH ; Scan for a Space
- Repne Scasb ; Do the scan
- Xchg SI,DI ; Restore SI & DI (SI past the SPACE!)
- Jne End_File ; Sorry, no Space found, end the name
- Inc AH ; AH = 0 (else we exit!)
- Skip_Scan: Mov CX,3 ; Three characters MAX for extension
- Jz Next_Char ; Back we go for the extension
- End_File: Mov [DI],BL ; There isn't one, end the FileName here
- FileDone: Ret
-
- CheckChar: Cmp AL,BH ; Space is OK
- Je Char_Ok
- Cmp AL,BH ; '.' or 0h is OK
- Je Char_Ok
- Cmp AL,'0' ; Ctrl-Chars !"#$%'&()*+,-./ are no good
- Jb Bad_Char
- Cmp AL,'9' ; 0-9 are OK
- Jbe Char_Ok
- Cmp AL,'A' ; ;:<=>? are no good
- Jb Bad_Char
- Cmp AL,'Z' ; A-Z are OK
- Jbe Char_Ok ; Anything else is no good
- Bad_Char: Mov AL,'$' ; Replace all bad characters with '$'
- Char_Ok: Ret
-
- ;---------------------------------------;
- ; Transfer Date from yymmdd to mm-dd-yy ;
- ;---------------------------------------;
-
- TransferDate: Mov BL,'-'
- Lodsw ; Read Year
- Movsw ; Copy Month
- Mov [DI],BL ; Write '-'
- Inc DI
- Movsw ; Copy Day
- Mov [DI],BL ; Write '-'
- Inc DI
- Stosw ; Write year
- Ret
-
- ;------------------------------------------;
- ; This subroutine will converts a byte ;
- ; into ascii text ;
- ;------------------------------------------;
-
- TransferChr: Lodsb ;Read the Chr
- Xor AH,AH ;force upper byte to zero
- Mov DX,3 ;We want 3 characters
- Jmp SHORT TI2
-
- ;------------------------------------------;
- ; This subroutine will converts an integer ;
- ; into ascii text ;
- ;------------------------------------------;
-
- TransferInt: Lodsw ;Read the integer
- TransferInt2: Mov DX,5 ;We want 5 characters
- TI2: Push BX ;Save register
- Mov BL,10 ;for division by 10
- Xor CX,CX ;set count to zero
- Divide: Push DX ;save register
- Xor DX,DX ;perform word divide
- Xor BH,BH ; to avoid divide overflow
- Div BX ;return quotient in AX
- Mov BH,DL ;return remainder in BH
- Pop DX
- Push BX ;build our number on the stack
- Inc CX ;keep count of them
- Or AX,AX ;All done? (remainder = 0)
- Jnz Divide ;No, Keep dividing
- Mov AH,"0" ;prepare for ASCII translation
- Write_it: Pop BX ;get a remainder off the stack
- Mov AL,BH ;put remainder in AL
- Add AL,AH ;convert to ASCII
- Stosb ;write digit to end of string
- Dec DX ;decrement desired count
- Loop Write_it ;pop all of them off of stack
- Mov CX,DX ;Remaining Count to CX
- Pop BX ;Retore register
-
- Jcxz PadDone ;No padding needed
- Xor AL,AL ;Load Zero
- Rep Stosb ;Pad remainder
- PadDone: Ret ;All Done!
-
-
- ;-------------------------------------------;
- ; DX Points to ASCIIZ Filename ;
- ; ;
- ; Check to see if file in current directory ;
- ; or at %PCBDRIVE%%PCBDIR% from environment ;
- ;-------------------------------------------;
-
- CheckFile: Push DX ;Save filename pointer
- Mov AX,3D40H ;Open file for reading.
- Int 21H
- Jc CheckError ;Error if Carry Set
- Mov AX,BX ;Copy handle of open file
- Mov AH,3Eh ;and close it.
- Int 21H
- Jnc CheckDone ;OK, File exists
- CheckError: Cmp AX,2 ;File Not Found?
- Jne CheckDone ;Exit if anything else
- Mov BX,OFFSET UserBuffer
- Pop SI ;Get filename pointer
- Push BX ;Save Buffer Address instead
- Push SI ;Now save filename pointer
- Mov DX,OFFSET PCBDrive
- Mov BP,LenPCBDrive
- Call Copy_Env ;Findit & Copy it
- Mov DX,OFFSET PCBDir
- Mov BP,LenPCBDir
- Call Copy_Env ;Findit & Copy it
- Pop SI ;Get back filename pointer
- Mov AL,'\' ;Append a '\' (if needed)
- Cmp [DI-1],AL ;Is there one already?
- Je No_Slash ;Yes,
- Stosb ;No, so add one.
- No_Slash: Call Copy_ASCIIZ ;And Copy it
- Stosb ; And terminate it with a Zero
- ; Pop SI ;Get the buffer address
- ; Push SI ; put it back on the stack
- ; Call DisplayText ; Now, Lets see that name!
- CheckDone: Pop DX ;Get Filename pointer or buffer address.
- Ret
-
- ;------------------------------------------------------;
- ; On Entry: ;
- ; BX Points to Destination Buffer ;
- ; DX points to Target String to find in Environment ;
- ; BP Contains length of Target String ;
- ; On Exit: ;
- ; BX adjusted to next character to write in Buffer ;
- ; DI is same as BX (All other Regs altered) ;
- ;------------------------------------------------------;
-
- Copy_Env: Mov AX,CS:[2Ch] ;Point ES to Environment
- Mov ES,AX ;
- Xor DI,DI ;Start of Environment (ES:DI)
- Xor AX,AX ;
- Next_Env: Mov CX,BP ;Get length.
- Mov SI,DX ;Get Target pointer
- Rep Cmpsb ;Do we have a match? (DS:SI) = (ES:DI)
- Je FoundMatch ;Yes, Found it
- Dec DI ;No, It didn't match, back up one
- Mov CX,-1 ;
- Repne Scasb ;Find the end of this one (ES:DI)
- Cmp ES:[DI],AL ;Is this the last one?
- Jne Next_Env ;No, Do the next one.
- Mov DI,BX ;Point DI to Buffer also
- Je Copy_Exit ;Yes, No Copy
-
- FoundMatch: Mov AX,ES ;Point DS to Env Segment
- Mov DS,AX ;
- Mov AX,CS ; and ES back to Program Data Segment
- Mov ES,AX ;
- Mov SI,DI ;Point SI to variable value
- Mov DI,BX ;Point DI to Buffer
-
- Copy_ASCIIZ: Xor AL,AL ;We need to copy up to the 0h
- Copy_Next: Cmp [SI],AL ;Is this the end?
- Je Copy_Done ;Yes,
- Movsb ;No, Copy it (ES:DI) <= (DS:SI)
- Jne Copy_Next ;Keep going
- Copy_Done: Mov BX,DI ;Update BX
- Copy_Exit: Mov DX,CS ;Make sure DS points to
- Mov DS,DX ; Code Segment again.
- Mov ES,DX ; and ES too!
- Ret ;
-
- ;--------------------------------;
- ; DX Points to ASCIIZ Filename ;
- ; DI Points to Buffer Area ;
- ; CX Contains Length to read ;
- ; AX Contains Record Number or 0 ;
- ; Carry set if error ;
- ;--------------------------------;
-
- ReadBuffer: Mov SI,DX ;Save filename pointer (for disp)
- Push AX ;Save Record Number (if any)
- Mov AX,3D40H ;Open file for reading.
- Int 21H
- Pop BX ;Restore Record Number (to BX)
- Jc FileError ;Error if Carry Set
- Xchg AX,BX ;Copy handle of open file
- Or AX,AX ;Random Record Seek?
- Jz No_Seek ;No,
- Push CX
- Dec AX
- Mul CX ;Yes, CX=Length, AX=Record Number
- ;Now DX:AX = Seek (Save Length)
- Mov CX,AX ;Now DX:CX
- Xchg CX,DX ;Now CX:DX
- Mov AX,4200H ;Seek
- Int 21H
- Pop CX ;Restore Length
- Jc FileError ;Error if Carry Set
- No_Seek: Mov DX,DI ;Point to buffer
- Mov AH,3FH ;Read from handle
- Int 21H
- Jc FileError ;Error if Carry Set
- Mov AH,3EH ;Close file
- Int 21H
- Jc FileError
- Ret ;All done
- FileError: Push AX ;Save error code
- Call DisplayText ;Display the filename
-
- ;For trouble shooting error codes use the following
-
- ; Mov DL,' '
- ; Mov AH,2 ;Character Output
- ; Int 21H
- ; Mov DL,'('
- ; Mov AH,2 ;Character Output
- ; Int 21H
- ; Mov DL,BL
- ; Add DL,30h
- ; Mov AH,2 ;Character Output
- ; Int 21H
- ; Mov DL,')'
- ; Mov AH,2 ;Character Output
- ; Int 21H
- Pop AX ;Get error code
- Call File_Error ;Translate it
- Stc ;Indicate the error
- Ret
-
- SUB_TABLE LABEL BYTE
- DB 'F', 25, 0, 15 ; First Name (Proper Case)
- DB '?', 40, 0, 12 ; Password
- DB 'G', 56, 0, 5 ; Time User logged On
- DB 'Z', 80, 0, 4 ; Language Extension
- DB 'N', 84, 0, 25 ; User Full Name
- DB '*', 146, 1, 5 ; Time Remaining (from 109)
- DB 'V', 112, 0, 5 ; Event Time
- DB 'C', 153, 0, 24 ; City, State
- DB 'B', 189, 0, 13 ; Bus/Data Phone
- DB 'H', 202, 0, 13 ; Home/Voice Phone
- DB 'D', 106, 1, 8 ; Last Date On (from 215)
- DB 'T', 221, 0, 5 ; Last Time On
- DB '!', 226, 0, 1 ; Expert Mode (Y or N)
- DB 'P', 227, 0, 1 ; Default Protocol
- DB 'L', 114, 1, 8 ; Last Dir Scan (from 229)
- DB 'A', 122, 1, 3 ; Sec Level Access (from 235)
- DB '#', 125, 1, 5 ; Number of Times On (from 236)
- DB 'M', 130, 1, 5 ; TimeSpent last call (from 311)
- DB 'E', 135, 1, 8 ; Expiration Date (from 313)
- DB 'X', 143, 1, 3 ; Expiration Sec Level (from 319)
- DB 'U', 251, 0, 30 ; User Maintained Comment
- DB 'S', 25, 1, 30 ; Sysop Maintained Comment
- DB 'R', 101, 1, 5 ; Record Number
- DB '=', 151, 1, 13 ; First.Last
- DB '$', 101, 1, 63 ; Translated Data
-
- Table_End DB 0 ; 528 DUP ('.') ;PCBoard.Sys reads in here
- SysBuffer EQU Table_End + 1
-
- ; 0 Display AS STRING * 2 'Display On/Off ("-1" = On, " 0" = Off)
- ; 2 Printer AS STRING * 2 'Printer On/Off ("-1" = On, " 0" = Off)
- ; 4 PageBell AS STRING * 2 'Page Bell On/Off ("-1" = On, " 0" = Off)
- ; 6 CallAlarm AS STRING * 2 'Caller Alarm On/Off ("-1" = On, " 0" = Off)
- ; 8 SysopFlag AS STRING * 1 'Sysop Flag (" ", "N"=sysop next, "X"=exit dos)
- ; 9 ErrCorr AS STRING * 2 'Error Corrected ("-1" = On, " 0" = Off)
- ; 11 Graphics AS STRING * 1 'Graphics Mode ('Y'=yes, 'N'=no, '7'=7E1)
- ; 12 NodeChat AS STRING * 1 'Node Chat Status ('A'=available, 'U'=unavailable)
- ; 13 DTEPort AS STRING * 5 'DTE Port Speed (PC to Modem speed)
- ; 18 Connect AS STRING * 5 'Connect Speed shown to caller or "Local"
- ;| 23 RecNum AS INTEGER 'User's Record Number in the USERS file
- ;| 25 FirstName AS STRING * 15 'User's First Name (padded to 15 characters)
- ;| 40 Password AS STRING * 12 'User's Password (padded to 12 characters)
- ; 52 TimeOn AS INTEGER 'Time User Logged On (in minutes since midnight)
- ; 54 TimeUsed AS INTEGER 'Time used so far today (negative number of minutes)
- ;| 56 TimeOnF AS STRING * 5 'Time User Logged On (in "HH:MM" format)
- ; 61 DayTime AS INTEGER 'Time Allowed On (from PWRD file)
- ; 63 DLKbytes AS INTEGER 'Allowed K-Bytes for Download
- ; 65 ConfArea AS STRING * 1 'Conference Area user was in (if <= 255)
- ; 66 ConfJoined AS STRING * 5 'Conference Areas the user has joined this session
- ; 71 ConfScaned AS STRING * 5 'Conference Areas the user has scanned this session
- ; 76 ConfAddTime AS INTEGER 'Conference Add Time in minutes
- ; 78 CreditTime AS INTEGER 'Upload/Sysop CHAT Credit Minutes
- ;| 80 LangExt AS STRING * 4 'Language Extension
- ;| 84 UserName AS STRING * 25 'User's Full Name (padded to 25 characters)
- ;| 109 MinRemain AS INTEGER 'Calculated Minutes Remaining
- ; 111 NodeNum AS STRING * 1 'Node Number (or ' ' if no network) CHR$()
- ;| 112 EventTime AS STRING * 5 'Scheduled Event Time (in "HH:MM" format)
- ; 117 EventOn AS STRING * 2 'Is Event Active ("-1" = On, " 0" = Off)
- ; 119 EventSlide AS STRING * 2 'Slide Event ("-1" = On, " 0" = Off)
- ; 121 MemMesg AS STRING * 4 'Memorized Message Number MKSMBF$()
- ; 125 ComPort AS STRING * 1 'Comm Port Number (0=none, 1-8)
- ; 126 Reserved1 AS STRING * 1 'Reserved for PCBoard
- ; 127 Reserved2 AS STRING * 1 'Reserved for PCBoard
-
- UserBuffer EQU SysBuffer+128 ;Users record reads in here
-
- ;| 128 UserName AS STRING * 25 'First name and Last name
- ;| 153 CityState AS STRING * 24 'City and State
- ; 177 Password AS STRING * 12 'Password
- ;| 189 BusPhone AS STRING * 13 'Business Phone Number
- ;| 202 HomePhone AS STRING * 13 'Home Phone Number
- ;| 215 LastOnDate AS STRING * 6 'Last Date on system (in yymmdd format)
- ;| 221 LastOnTime AS STRING * 5 'Last Time on system (in hh:mm format)
- ;| 226 Expert AS STRING * 1 'Expert Mode - "Y" or "N"
- ;| 227 Protocol AS STRING * 1 'Protocol
- ; 228 PackedFlags AS STRING * 1 'Dirty, ClrScrn, HasMail, DontAsk, Editor
- ;| 229 LastDirScan AS STRING * 6 'Last date looked at directory (in yymmdd format)
- ;| 235 SecLevel AS STRING * 1 'Security Level CHR$(X)
- ;| 236 TimesOn AS INTEGER 'Number of times on the system
- ; 238 PageLength AS STRING * 1 'Page Length CHR$(X)
- ; 239 Uploads AS INTEGER 'Number of Uploads
- ; 241 Downloads AS INTEGER 'Number of Downloads
- ; 243 DailyDlBytes AS STRING * 8 'Daily Download Bytes so far
- ;| 251 UserComment AS STRING * 30 'User Maintained Comment
- ;| 281 SysopComment AS STRING * 30 'Sysop Maintained Comment
- ;| 311 TimeSpent AS INTEGER 'Elapsed Time on system on last date called
- ;| 313 SubDate AS STRING * 6 'Subscription Registration Date (yymmdd format)
- ;| 319 ExpSecLevel AS STRING * 1 'Subscription Expired Security Level CHR$(X)
- ; 320 LastConference AS STRING * 1 'Last Conference left - CHR$(X) - 255 = Ext.
- ; 321 AreaReg AS STRING * 5 'Area Registration Info (1-39) BitMap
- ; 326 ExpAreaReg AS STRING * 5 'Expired Area Registration Info (1-39) BitMap
- ; 331 UserScanArea AS STRING * 5 'User Message Scan Areas (1-39) BitMap
- ; 336 TotalDownloads AS STRING * 8 'Total Bytes Download - all calls
- ; 344 TotalUploads AS STRING * 8 'Total Bytes Upload - all calls
- ; 352 Delete AS STRING * 1 'Positive Delete Flag to Delete User (Repack)
- ; 353 LastMsgMain AS STRING * 4 'Last message read in Main Board MKSMBF$()
- ; 357 LastMsgConf AS STRING * 156 'Last message read in Conferences 39 * 4 "
- ; ' (Gets overwritten by 3 date conversions)
- ; ' ( & numeric conversions)
- ; 513 InfPointer AS LONG 'Pointer into USERS.INF record
- ; 517 Space2 AS STRING * 9 'Reserved
- ; 526 ExtLastConference AS INTEGER 'Last Conference Left (If LastConf.$ = 255)
-
- DatBuffer EQU UserBuffer+400 ;PCBoard.Dat read in here
- ;and we buffer or conversions.
-
- CODE ENDS
- END Start
-